package cn.elead.chaos.sso.server.web.pwd.controller;

import java.util.HashMap;
import java.util.Map;

import javax.mail.MessagingException;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import cn.elead.chaos.email.domain.CustomMailMessage;
import cn.elead.chaos.email.service.IEmailService;
import cn.elead.chaos.mybatils.web.controller.BaseController;
import cn.elead.chaos.sso.server.web.login.service.RedisSaveService;
import cn.elead.chaos.sso.server.web.pwd.domain.PwdEdit;
import cn.elead.chaos.sso.server.web.pwd.domain.SsoPwd;
import cn.elead.chaos.sso.server.web.pwd.service.ISsoPwdService;
import cn.elead.chaos.sso.server.web.system.domain.SysUser;
import cn.elead.chaos.sso.server.web.system.service.ISysUserService;
import cn.elead.chaos.sso.server.web.system.service.impl.SysPasswordService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 密码修改记录控制器
 * 
 * @author luopeng
 *
 */
@Slf4j
@Controller
public class PasswordController extends BaseController {

	private String prefix = "pwd";

	private char EMAIL_CHAR = '@';

	@Value("${spring.mail.username:it@e-lead.cn}")
	private String fromMail;

	@Value("${spring.mail.suffix:e-lead.cn}")
	private String emailSuffix = "e-lead.cn";

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ISsoPwdService ssoPwdService;

	@Autowired
	private RedisSaveService redisSaveService;

	@Autowired
	private SysPasswordService sysPasswordService;

	@Autowired
	private IEmailService emailService;

	@GetMapping("password/new")
	public String newPassword() {
		return prefix + "/new";
	}

	@PostMapping("password/new")
	public String toEmail(Model model, String email) throws MessagingException {
		if (StrUtil.isBlank(email)) {
			model.addAttribute("errorMsg", "请输入邮箱");
			return newPassword();
		}
		if (StrUtil.contains(email, EMAIL_CHAR)) {
			email = StrUtil.subBefore(email, EMAIL_CHAR, true);
		}
		if (StrUtil.isBlank(email)) {
			model.addAttribute("errorMsg", "请输入正确格式");
			return newPassword();
		}

		SysUser user = userService.selectUserByLoginName(email);
		if (ObjectUtil.isNull(user)) {
			model.addAttribute("errorMsg", "请输入正确账号信息");
			return newPassword();
		}
		// 发送邮件
		CustomMailMessage message = new CustomMailMessage();
		message.setFrom(fromMail);
		String to = email + EMAIL_CHAR + emailSuffix;
		log.info("to:{}", to);
		message.setTo(to);

		String link = createLink(user);
		log.info("link:{}", link);
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("baseUrl", getBasePath());
		variables.put("name", user.getUserName());
		variables.put("email", to);
		variables.put("link", link);

		message.setVariables(variables);
		emailService.sendHtmlMail(message);
		// 邮件发送成功
		if (message.isIfSuccess()) {
			model.addAttribute("email", email + EMAIL_CHAR + emailSuffix);
			return prefix + "/email";
		}
		// 邮件发送失败
		model.addAttribute("errorMsg", "邮件发送失败");
		return newPassword();
	}

	@GetMapping("password/edit")
	public String toEdit(Model model, @RequestParam(value = "email", required = false) String email, @RequestParam(value = "reset_password_token", required = false) String token) {

		if (StrUtil.isBlank(email)) {
			model.addAttribute("errorMsg", "id参数为空");
			return prefix + "/email";
		}
		if (StrUtil.isBlank(token)) {
			model.addAttribute("errorMsg", "sid参数为空");
			return prefix + "/email";
		}
		SysUser user = redisSaveService.getPwdCode(token);
		if (ObjectUtil.isEmpty(user)) {
			// 删除记录
			model.addAttribute("errorMsg", "已经过期,请重新修改");
			return prefix + "/email";
		}
		
		SsoPwd ssoPwd = ssoPwdService.selectSsoPwdByToken(token);
		if (ObjectUtil.isNotNull(ssoPwd) && ssoPwd.getStatus() !=2) {
			model.addAttribute("errorMsg", "密码已修改完成");
			return prefix + "/success";
		}

		model.addAttribute("userId", user.getUserId());
		model.addAttribute("username", user.getUserName());

		return prefix + "/edit";
	}

	@PostMapping("password/edit")
	public String edit(Model model, @ModelAttribute PwdEdit pwdEdit) {

		String userId = pwdEdit.getUserId();
		if (StrUtil.isBlank(userId)) {
			model.addAttribute("errorMsg", "userId参数为空");
			return prefix + "/email";
		}
		String password = pwdEdit.getPassword();
		String newPassword = pwdEdit.getNewPassword();

		if (StrUtil.isBlank(password)) {
			SysUser user = userService.selectUserById(userId);
			model.addAttribute("userId", user.getUserId());
			model.addAttribute("username", user.getUserName());
			model.addAttribute("errorMsg", "密码不为空");
			return prefix + "/edit";
		}

		int length = password.length();
		if (length < 6 || length > 20) {
			SysUser user = userService.selectUserById(userId);
			model.addAttribute("userId", user.getUserId());
			model.addAttribute("username", user.getUserName());
			model.addAttribute("errorMsg", "密码长度在 6 到 20 个字符");
			return prefix + "/edit";
		}

		if (!password.equals(newPassword)) {
			SysUser user = userService.selectUserById(userId);
			model.addAttribute("userId", user.getUserId());
			model.addAttribute("username", user.getUserName());
			model.addAttribute("errorMsg", "密码不一致");
			return prefix + "/edit";
		}
		
		SsoPwd ssoPwd = ssoPwdService.selectSsoPwdById(userId);
		if (ObjectUtil.isNotNull(ssoPwd) && ssoPwd.getStatus() !=2) {
			model.addAttribute("errorMsg", "密码已修改完成");
			return prefix + "/success";
		}

		SysUser user = new SysUser();
		user.setUserId(userId);
		user.setPassword(sysPasswordService.encryptPassword(newPassword));
		userService.resetUserPwd(user);
		
		ssoPwd.setStatus(4L);
		ssoPwd.setDelFlag("1");
		ssoPwdService.updateSsoPwd(ssoPwd);
		return prefix + "/success";
	}

	/**
	 * @Description: 生成邮箱链接地址
	 * @author luopeng
	 * @date 2016-11-3 下午01:50:14
	 */
	public String createLink(SysUser user) {
		
		String token = null;
		// 是否存在没有处理的修改日志
		SsoPwd ssoPwd = ssoPwdService.selectSsoPwdById(user.getUserId());
		if (ObjectUtil.isNotNull(ssoPwd)) {
			SysUser redisuser = redisSaveService.getPwdCode(ssoPwd.getValidataCode());
			// 没有失效
			if (ObjectUtil.isNotEmpty(redisuser)) {
				// token继续使用
				token = ssoPwd.getValidataCode();
			}else {
				token = RandomStringUtils.randomAlphanumeric(10);
			}
		}else {
			token = RandomStringUtils.randomAlphanumeric(10);
			ssoPwd = new SsoPwd();
			ssoPwd.setId(user.getUserId());
			ssoPwd.setStatus(2L);
			ssoPwd.setValidataCode(token);
			ssoPwdService.insertSsoPwd(ssoPwd);
		}
		// 保存3天
		redisSaveService.savePwdCodeToRedis(token, user);
		String email = user.getLoginName() + EMAIL_CHAR + emailSuffix;
		String resetPassHref = getBasePath() + "/password/edit?email=" + email + "&reset_password_token=" + token;
		return resetPassHref;
	}

	/**
	 * baseUrl
	 * 
	 * @return
	 */
	private String getBasePath() {
		StringBuffer url = new StringBuffer();
		String path = request.getContextPath();
		int serverPort = request.getServerPort();
		String scheme = request.getScheme();
		String serverName = request.getServerName();
		url.append(scheme).append("://").append(serverName);
		if (serverPort != 80) {
			url.append(":").append(serverPort);
		}
		url.append(path);
		return url.toString();
	}
}